from fdfs_client.client import Fdfs_client

from mall import settings
from django.core.files.storage import Storage
from django.utils.deconstruct import deconstructible
# 编写自定义存储系统
# 1、自定义存储系统必须是以下子类 django.core.files.storage.Storage
# 2、Django必须能够在没有任何参数的情况下实例化您的存储系统。这意味着任何设置都应该来自django.conf.settings
# 3、您的存储类必须实现_open()和_save() 方法以及适用于您的存储类的任何其他方法。
# 此外，如果您的类提供本地文件存储，则它必须覆盖该path()方法。
# 4、您的存储类必须是可解构的， 以便在迁移中的字段上使用时可以对其进行序列化。只要您的字段具有可自行序列化的参数，就 可以使用 django.utils.deconstruct.deconstructible类装饰器（这就是Django在FileSystemStorage上使用的）。
@deconstructible
class MyStorage(Storage):

    def __init__(self, client_path=None, ip=None):
        if client_path is None:
            self.client_path = settings.FDFS_CLIENT_CONF

        if ip is None:
            self.ip = settings.FDFS_URL

    # open是打开文件的方法
    # 我们采用fastdfs的storage实现文件的下载，因此不需要此方法
    def _open(self, name, mode='rb'):
        pass

    # 我们需要自己实现fastdfs的文件上传
    def _save(self, name, content, max_length=None):
        # 获取上传的内容
        # content是上传的内容
        file_data = content.read()

        # 通过fdfs上传
        # client = Fdfs_client(settings.FDFS_CLIENT_CONF)
        client = Fdfs_client(self.client_path)
        # buffer 二进制流
        result = client.upload_by_buffer(file_data)

        # 判断上传结果(是个字典，如下)并返回
        """
        {'Remote file_id': 'group1/M00/00/00/wKjlhFsTgJ2AJvG_AAAyZgOTZN0850.jpg', 
         'Uploaded size': '12.00KB',
         'Local file name': '/home/python/Desktop/images/0.jpg', 
         'Storage IP': '192.168.229.132',
         'Group name': 'group1', 
         'Status': 'Upload successed.'}
        """
        if result.get('Status') == 'Upload successed.':
            # 说明上传成功
            return result.get('Remote file_id')
        else:
            raise Exception('上传失败')

    # FDFS有自己的文件存储系统，如果上传相同的文件
    # 它可以自己处理同名问题
    def exists(self, name):
        return False

    # 返回文件内容
    # name就是Remote file_id
    def url(self, name):
        return self.ip + name